//
//  GCDViewController.m
//  MyProject
//
//  Created by yun on 2018/7/10.
//  Copyright © 2018年 yun. All rights reserved.
//

#import "GCDViewController.h"

@interface GCDViewController ()

@end

@implementation GCDViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];
    [self dispatchGroupNotifyDemo];
}

- (void)dispatchGroupWaitDemo {
    dispatch_queue_t concurrentQueue = dispatch_queue_create("com.starming.gcddemo.concurrentqueue",DISPATCH_QUEUE_CONCURRENT);
    dispatch_group_t group = dispatch_group_create();
    //在group中添加队列的block
    dispatch_group_async(group, concurrentQueue, ^{
        [NSThread sleepForTimeInterval:2.f];
        NSLog(@"1");
    });
    dispatch_group_async(group, concurrentQueue, ^{
        NSLog(@"2");
    });
    dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
    NSLog(@"go on");
}

- (void)dispatchGroupNotifyDemo {
    dispatch_queue_t concurrentQueue = dispatch_queue_create("com.starming.gcddemo.concurrentqueue",DISPATCH_QUEUE_CONCURRENT);
    dispatch_group_t group = dispatch_group_create();
    dispatch_group_async(group, concurrentQueue, ^{
        NSLog(@"1");
    });
    dispatch_group_async(group, concurrentQueue, ^{
        NSLog(@"2");
    });
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"end");
    });
    NSLog(@"can continue");
    
}


- (void)gcd{
    /**
     * 同步+串行队列:
     同步:提交blcok对象以在调度队列上执行，并等待该blcok完成。
     不创建多线程，顺序执行任务(blcok执行完才会执行下面的任务，无论是同步中的还是主队列的)
     主线程+串行会死锁:主线程未结束，block未开始，相互等待导致死锁
     */
    
    dispatch_queue_t serialQueue = dispatch_queue_create("serialQueue", DISPATCH_QUEUE_SERIAL);
    dispatch_queue_t concurrentQueue = dispatch_queue_create("concurrentQueue", DISPATCH_QUEUE_CONCURRENT);
    dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_queue_t mainQueue = dispatch_get_main_queue();
    NSLog(@"start==%@",[NSThread currentThread]);
    /*
    dispatch_sync(serialQueue, ^{
        NSLog(@"1==%@",[NSThread currentThread]);
    });
    dispatch_sync(serialQueue, ^{
        NSLog(@"2==%@",[NSThread currentThread]);
        dispatch_sync(serialQueue, ^{//serialQueue未结束，该blcok未开始，死锁
            NSLog(@"3==%@",[NSThread currentThread]);
        });
    });
    dispatch_sync(serialQueue, ^{
        NSLog(@"4==%@",[NSThread currentThread]);
    });
    
    */
    
    /**
     * 同步+并行队列:
     同步:提交blcok对象以在调度队列上执行，并等待该blcok完成。
     不创建多线程，顺序执行任务
     */
    /*
    dispatch_sync(concurrentQueue, ^{
        NSLog(@"1==%@",[NSThread currentThread]);
        dispatch_sync(concurrentQueue, ^{// 可以执行，任务是并列执行，无需等待concurrentQueue队列执行完
            NSLog(@"2==%@",[NSThread currentThread]);
        });
    });
    
    dispatch_sync(concurrentQueue, ^{
        NSLog(@"3==%@",[NSThread currentThread]);
        dispatch_sync(serialQueue, ^{// 同理可以执行
            NSLog(@"4==%@",[NSThread currentThread]);
        });
    });
    
    dispatch_sync(concurrentQueue, ^{
        NSLog(@"5==%@",[NSThread currentThread]);
    });
    */
    
    /**
     * 异步+串行:
     异步：在调度队列上提交异步执行block并立即返回。
     自定义队列可以开辟子线程，主队列不能开辟子线程
     */
    /*
    dispatch_async(mainQueue, ^{
        NSLog(@"1==%@",[NSThread currentThread]);
        dispatch_async(serialQueue, ^{
            NSLog(@"2==%@",[NSThread currentThread]);
        });
    });
    
    dispatch_async(serialQueue, ^{
        NSLog(@"3==%@",[NSThread currentThread]);
        dispatch_async(mainQueue, ^{
            NSLog(@"4==%@",[NSThread currentThread]);
        });
    });
    
    dispatch_async(mainQueue, ^{
        NSLog(@"5==%@",[NSThread currentThread]);
    });
    */
    
    /**
     * 异步+并行:
     异步：在调度队列上提交异步执行block并立即返回。
     可以创建子线程
     */
    /*
    dispatch_async(globalQueue, ^{
        NSLog(@"1==%@",[NSThread currentThread]);
        dispatch_async(concurrentQueue, ^{
            NSLog(@"2==%@",[NSThread currentThread]);
        });
    });
    
    dispatch_async(concurrentQueue, ^{
        NSLog(@"3==%@",[NSThread currentThread]);
        dispatch_async(globalQueue, ^{
            NSLog(@"4==%@",[NSThread currentThread]);
        });
    });
    
    dispatch_async(concurrentQueue, ^{
        NSLog(@"5==%@",[NSThread currentThread]);
    });
    */
    
    
    NSLog(@"end==%@",[NSThread currentThread]);
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end
